﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpModelInterface.h"
#include "Vector3d.h"

namespace gcmp
{
    class IGraphicsNodeReference;

    /// \brief 斑马纹模式
    enum class ZebraMode : int8_t
    {
        Sphere  = 0,    ///< 球面斑马纹模式
        Cylinder= 1,    ///< 圆柱斑马纹模式
        Count   = 2     ///< 斑马纹模式数量
    };

    /// \brief 斑马纹颜色模式
    enum class ZebraColorEffectMode : int8_t
    {
        WithLighting = 0,  ///< 光照与斑马纹混合
        OnlyZebra = 1,     ///< 只有斑马纹
    };

    /// \brief 面顶点的入射方向模式
    enum class ZebraIncidentDirectionMode : int8_t
    {
        ViewPoint = 0,     ///< 视点到曲面点
        ScreenNormal = 1   ///< 屏幕法向
    };

    /// \brief 斑马纹视点模式
    enum class ZebraViewPointMode : int8_t
    {
        ScreenCamera = 0,   ///< 屏幕摄像机视点
        CustomViewPoint = 1 ///< 自定义视点
    };

    /// \brief 斑马纹参数
    struct GCMP_MODEL_INTERFACE_EXPORT ZebraOptions
    {
        ZebraMode Mode = ZebraMode::Sphere;                                                         ///< 斑马纹模式：圆柱模式、球面模式
        ZebraColorEffectMode ColorEffectMode = ZebraColorEffectMode::WithLighting;                  ///< 斑马纹显示颜色模式：指定是否只显示斑马纹的颜色，或者是和曲面本身颜色的混色
        ZebraIncidentDirectionMode IncidentDirectionMode = ZebraIncidentDirectionMode::ViewPoint;   ///< 面顶点的入射方向模式：指定面顶点的入射方向是屏幕坐标系法向，或者是视点到该点的方向
        ZebraViewPointMode ViewPointMode = ZebraViewPointMode::ScreenCamera;                        ///< 设置斑马纹视点模式：用户指定或屏幕视点；当斑马纹设置为用户指定时，需要设置斑马纹视点位置
        UInt16 StripeNumber = 20;                                                                   ///< 斑马纹条纹数量
        double StripeRatio = 0.5;                                                                   ///< 默认黑白条纹等宽，范围[0,1] 
        double StripeColorIntense = 1.0;                                                            ///< 默认颜色最浓，范围[0,1]
        double Radius = 1000.0;                                                                     ///< 圆柱模式下的圆柱半径或球面模式下的球面半径，必须大于 0
        double StripeSharpen = 1.0;                                                                 ///< 默认条纹锐化程度，范围[0,1],锐化程度越高，条纹黑白越分明
        Vector3d Direction = Vector3d(1.0, 0.0, 0.0);                                               ///< 圆柱模式下圆柱中心线方向或球面模式下球面条纹排列方向
        Vector3d Center = Vector3d(0.0, 0.0, 0.0);                                                  ///< 圆柱模式下圆柱中心线起点坐标或球面模式下球心坐标
        Vector3d CustomViewPoint = Vector3d(0.0, 0.0, 0.0);                                         ///< 当斑马纹设置为用户指定时，需要设置斑马纹视点位置       
    
        /// \brief 斑马纹参数是否有效
        bool IsValid() const;

        /// \brief 斑马纹参数是否相等
        ///
        /// \param another 对比对象
        bool operator==(const ZebraOptions &another) const;

        /// \brief 斑马纹参数是否不等
        ///
        /// \param another 对比对象
        bool operator!=(const ZebraOptions &another) const;

        /// \brief 斑马纹参数前者是否小于后者
        ///
        /// \param another 对比对象
        bool operator<(const ZebraOptions& another) const;

    };

    /// \brief 斑马纹效果管理器
    class GCMP_MODEL_INTERFACE_EXPORT IZebraManager
    {
    public:
        virtual ~IZebraManager();

        /// \brief 开启或关闭斑马纹效果
        ///
        /// \param isToShow 是否开启
        virtual void ShowZebra(bool isToShow) = 0;

        /// \brief 斑马纹效果是否开启
        virtual bool IsZebraShowing() const = 0;

        /// \brief 设置斑马纹参数
        ///
        /// 内部检查 ZebraOptions 各字段有效性，如果无效就返回 false
        /// \param options 斑马纹参数
        /// \return 是否设置成功
        virtual bool SetZebraOptions(const ZebraOptions &options) = 0;

        /// \brief 获取斑马纹参数
        ///
        /// \return 斑马纹参数
        virtual const ZebraOptions& GetZebraOptions() const = 0;
        
        /// \brief 设置一个面是否显示斑马纹
        ///
        /// 一旦设置了面显示斑马纹，其他没设置的面就都不显示斑马纹
        /// \param face 需要设置的面
        /// \param isShownWithZebra 是否显示斑马纹
        virtual void ShowFaceWithZebra(const IGraphicsNodeReference &face, bool isShownWithZebra) = 0;

        /// \brief 设置场景中所有面都显示斑马纹
        virtual void ShowAllFacesWithZebra() = 0;

        /// \brief 查询某个面是否正显示斑马纹
        ///
        /// \param face 被查询的面
        /// \return true-显示斑马纹，false-不显示斑马纹
        virtual bool IsFaceShownWithZebra(const IGraphicsNodeReference &face) const = 0;

        /// \brief 查询是否场景中所有面都显示斑马纹
        ///
        /// \return true-都显示斑马纹，false-不都显示斑马纹
        virtual bool IsAllFacesShownWithZebra() const = 0;
    };   
}
